// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.network.packets.hit;

import java.nio.ByteBuffer;
import zombie.characters.IsoGameCharacter;
import zombie.characters.IsoZombie;
import zombie.core.network.ByteBufferWriter;
import zombie.core.raknet.UdpConnection;
import zombie.core.skinnedmodel.ModelManager;
import zombie.inventory.types.HandWeapon;
import zombie.network.GameClient;
import zombie.network.GameServer;
import zombie.network.ServerGUI;
import zombie.network.ServerMap;
import zombie.network.packets.INetworkPacket;

public class Zombie extends Character implements INetworkPacket {
    protected IsoZombie zombie;
    protected short zombieFlags;
    protected String attackOutcome;
    protected String attackPosition;

    public void set(IsoZombie _zombie, boolean isHelmetFall) {
        super.set(_zombie);
        this.zombie = _zombie;
        this.zombieFlags = 0;
        this.zombieFlags = (short)(this.zombieFlags | (short)(_zombie.isStaggerBack() ? 1 : 0));
        this.zombieFlags = (short)(this.zombieFlags | (short)(_zombie.isFakeDead() ? 2 : 0));
        this.zombieFlags = (short)(this.zombieFlags | (short)(_zombie.isBecomeCrawler() ? 4 : 0));
        this.zombieFlags = (short)(this.zombieFlags | (short)(_zombie.isCrawling() ? 8 : 0));
        this.zombieFlags = (short)(this.zombieFlags | (short)(_zombie.isKnifeDeath() ? 16 : 0));
        this.zombieFlags = (short)(this.zombieFlags | (short)(_zombie.isJawStabAttach() ? 32 : 0));
        this.zombieFlags |= (short)(isHelmetFall ? 64 : 0);
        this.zombieFlags = (short)(this.zombieFlags | (short)(_zombie.getVariableBoolean("AttackDidDamage") ? 128 : 0));
        this.attackOutcome = _zombie.getVariableString("AttackOutcome");
        this.attackPosition = _zombie.getPlayerAttackPosition();
    }

    @Override
    public void parse(ByteBuffer b, UdpConnection connection) {
        super.parse(b, connection);
        this.zombieFlags = b.getShort();
        this.attackOutcome = zombie.GameWindow.ReadString(b);
        this.attackPosition = zombie.GameWindow.ReadString(b);
        if (GameServer.bServer) {
            this.zombie = ServerMap.instance.ZombieMap.get(this.ID);
            this.character = this.zombie;
        } else if (GameClient.bClient) {
            this.zombie = GameClient.IDToZombieMap.get(this.ID);
            this.character = this.zombie;
        }
    }

    @Override
    public void write(ByteBufferWriter b) {
        super.write(b);
        b.putShort(this.zombieFlags);
        b.putUTF(this.attackOutcome);
        b.putUTF(this.attackPosition);
    }

    @Override
    public boolean isConsistent() {
        return super.isConsistent() && this.zombie != null;
    }

    @Override
    public String getDescription() {
        return super.getDescription()
            + "\n\tZombie [attack-position="
            + this.attackPosition
            + " | isStaggerBack="
            + ((this.zombieFlags & 1) != 0)
            + " | isFakeDead="
            + ((this.zombieFlags & 2) != 0)
            + " | isBecomeCrawler="
            + ((this.zombieFlags & 4) != 0)
            + " | isCrawling="
            + ((this.zombieFlags & 8) != 0)
            + " | isKnifeDeath="
            + ((this.zombieFlags & 16) != 0)
            + " | isJawStabAttach="
            + ((this.zombieFlags & 32) != 0)
            + " | isHelmetFall="
            + ((this.zombieFlags & 64) != 0)
            + " | attackDidDamage="
            + ((this.zombieFlags & 128) != 0)
            + " | attack-outcome="
            + this.attackOutcome
            + " ]";
    }

    @Override
    void process() {
        super.process();
        this.zombie.setVariable("AttackOutcome", this.attackOutcome);
        this.zombie.setPlayerAttackPosition(this.attackPosition);
        this.zombie.setStaggerBack((this.zombieFlags & 1) != 0);
        this.zombie.setFakeDead((this.zombieFlags & 2) != 0);
        this.zombie.setBecomeCrawler((this.zombieFlags & 4) != 0);
        this.zombie.setCrawler((this.zombieFlags & 8) != 0);
        this.zombie.setKnifeDeath((this.zombieFlags & 16) != 0);
        this.zombie.setJawStabAttach((this.zombieFlags & 32) != 0);
        this.zombie.setVariable("AttackDidDamage", (this.zombieFlags & 128) != 0);
    }

    protected void react(HandWeapon handWeapon) {
        if (this.zombie.isJawStabAttach()) {
            this.zombie.setAttachedItem("JawStab", handWeapon);
        }

        if (GameServer.bServer && (this.zombieFlags & 64) != 0 && !zombie.PersistentOutfits.instance.isHatFallen(this.zombie)) {
            zombie.PersistentOutfits.instance.setFallenHat(this.zombie, true);
            if (ServerGUI.isCreated()) {
                zombie.PersistentOutfits.instance.removeFallenHat(this.zombie.getPersistentOutfitID(), this.zombie);
                ModelManager.instance.ResetNextFrame(this.zombie);
            }
        }

        this.react();
    }

    @Override
    public IsoGameCharacter getCharacter() {
        return this.zombie;
    }
}
